`ifndef DEFINE_H
`define DEFINE_H

`define ON  1'b1
`define OFF 1'b0
`define ON_n 1'b0
`define OFF_n 1'b1
`define NULL 'b0

// `define BASE_ADDR 32'h8000_0000
// `define EXT_ADDR 32'h8040_0000
// `define DEV_ADDR 32'hA000_0000
`define BASE_ADDR 32'h3000_0000

// BRANCH
`define     P4         4'b0000
`define     BEQ        4'b0001
`define     BNE        4'b0010
`define     BGE        4'b0011
`define     BGEU       4'b0100
`define     BLT        4'b0101
`define     BLTU       4'b0110
`define     JAL        4'b1000
`define     JALR       4'b1001
`define     MRET       4'b1010

//SRC1
`define     S1_XXX     2'b00
`define     S1_PC      2'b01
`define     S1_RF1     2'b10

//SRC2
`define     S2_XXX     3'b000
`define     S2_4       3'b001
`define     S2_IMM     3'b010
`define     S2_RF2     3'b100
`define     S2_SA      3'b101//使用imm[4:0]
`define     S2_CSR     3'b110//使用修改前的csr值

//RF-Waddr
`define     RFaddr_XX   1'b0
`define     RFaddr_RD   1'b1

//RF-Wdata
`define     RFdata_ALU  1'b0
`define     RFdata_LOAD 1'b1

//Mask
`define     M_XXX    3'b000
`define     M_W      3'b001
`define     M_B      3'b010
`define     M_H      3'b011

`define     M_LBU    3'b110
`define     M_LHU    3'b111

//EXC
`define     EXC_OF   2'b00
`define     EXC_ON   2'b01
`define     EXC_EB   2'b10
`define     EXC_EC   2'b11

typedef logic[31:0] word_t;
typedef logic[4:0]  rfaddr_t;
typedef logic[11:0] rfcaddr_t;
typedef logic[5:0]  stall_t;

typedef struct packed{
    word_t pc;
    word_t debug_dnpc;
} if_to_id_bus_t;


typedef struct packed{
    word_t pc;
    word_t debug_dnpc;
    // logic  debug_brjmp;
    word_t inst;
    word_t alu_src1;
    word_t alu_src2;
    logic [3:0]  sel_alu_op;
    logic [2:0]  sel_mask;
    logic        dse;
    logic        dsw;
    logic        rfw;
    rfaddr_t     rf_waddr;
    logic        sel_rf_wdata;
    word_t       store_data;
    logic [1:0]  sel_exception;
    rfcaddr_t    rfc_waddr;
} id_to_exe_bus_t;

typedef struct packed{
    word_t pc;
    word_t debug_dnpc;
    // logic  debug_brjmp_en;
    word_t inst;
    logic load_en;
    logic store_en;
    word_t alu_result;
    word_t store_data;
    logic [2:0] sel_mask;

    logic rf_wen;
    rfaddr_t rf_waddr;
    logic sel_rf_wdata;

    logic [1:0] sel_exception;//同时表示是否ebreak、是否写入csr
    rfcaddr_t rfc_waddr;
    word_t rfc_wdata;//即csr值
} exe_to_mem_bus_t;

typedef struct packed{
    word_t pc;
    word_t debug_dnpc;
    // logic  debug_brjmp_en;
    logic  debug_load_en;
    logic  debug_store_en;
    word_t debug_ls_addr;
    word_t inst;

    logic rf_wen;
    rfaddr_t rf_waddr;
    word_t rf_wdata;

    logic [1:0] sel_exception;//同时表示是否ebreak、是否写入csr
    rfcaddr_t rfc_waddr;
    word_t rfc_wdata;
} mem_to_wb_bus_t;


typedef struct packed{
    logic rf_wen;
    rfaddr_t rf_waddr;
    word_t rf_wdata;

    logic rfc_wen;
    rfcaddr_t rfc_waddr;
    word_t rfc_wdata;
} wb_to_id_bus_t;

typedef struct packed{
    word_t debug_pc;
    word_t debug_dnpc; 
    // logic  debug_brjmp_en;
    word_t debug_inst;

    logic  debug_load_en;
    logic  debug_store_en;
    word_t debug_ls_addr;
    logic debug_ebreak_en;
} wb_to_dpic_bus_t;

typedef struct packed{
    logic brjmp_en;
    word_t brjmp_pc;
} id_to_if_bypass_t; // 不同跳转和异常跳转复用一个bypass

typedef struct packed{
    logic rf_wen;
    rfaddr_t rf_waddr;
    word_t rf_wdata;

    // logic rfc_wen;
    // rfaddr_t rfc_waddr;
    // word_t rfc_wdata;


} exe_to_id_bypass_t;

typedef struct packed{
    logic rf_wen;
    rfaddr_t rf_waddr;
    word_t rf_wdata;

    // logic rfc_wen;
    // rfaddr_t rfc_waddr;
    // word_t rfc_wdata;
} mem_to_id_bypass_t;


typedef struct packed {
    logic ecall_en;
    word_t wb_ecall_pc;
    word_t wb_ecall_inst;
} wb_to_front_bypass_t;


typedef struct packed {
    logic load_hazard_en;
    logic store_hazard_en;
    logic ecall_en;
} exe_to_front_bypass_t;
`endif
